package com.fingard.dsp.bank.directbank.srb01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.text.MFSHelper;
import com.fingard.text.StringHelper;
import com.fingard.util.SmbFileUtil;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.fingard.text.StringHelper.trimEndFileSp;

public class SRB01Base extends DirectBase implements ITcpClient {

    //解析单笔明细响应报文
    protected Map<String, String> parseRespMsg(String[] retStrArr, RetAtsTrans retAts, String actArea, Map<String, String> serialMap) throws Exception {
        Map<String, String> resultMap = new HashMap();
        String tmpRespCode = "";
        String tmpRespInfo = "";
        if (retStrArr[0].length() == 0) {
            StringBuilder curSbMsg = new StringBuilder();
            XmlTextReader curBkReader = loadBankRespXmlReader(retStrArr[1], curSbMsg);
            if (curBkReader != null) {
                String curRetCode = curBkReader.getFirstText("/ap/head/ret_code");
                String curRetInfo = curBkReader.getFirstText("/ap/head/ret_info");
                String curDataMFS = "";
                if ("0000".equals(curRetCode)) {
                    int curRecordNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/record_num"));
                    int curFieldNum = Integer.parseInt(curBkReader.getFirstText("/ap/body/field_num"));
                    if (curRecordNum > 0) {
                        String curFileFlag = curBkReader.getFirstText("/ap/head/file_flag");
                        String curFileName = curBkReader.getFirstText("/ap/body/file_name");
                        if ("1".equals(curFileFlag)) {
                            //共享目录方式
                            if (StringHelper.hasAnyChar(bankFront.bkTransFolder)) {
                                if (bankFront.bkTransFolder.startsWith("smb://")) {
                                    //下载共享目录批量查询文件
                                    String downloadFilePath = trimEndFileSp(bankFront.bkTransFolder) + File.separator;//共享目录路径
                                    String p_FileFullPath = getTempFileDirectory() + File.separator + Format.Time6Format.format(new Date());//下载到的本地路径
                                    StringBuilder p_sb = new StringBuilder();
                                    if (SmbFileUtil.smbDownload(p_FileFullPath, downloadFilePath, curFileName, p_sb) == 1) {
                                        p_FileFullPath = p_FileFullPath + File.separator + curFileName;
                                        WriteBankLogLn("文件下载成功，位于：" + p_FileFullPath);
                                        curDataMFS = FileHelper.readFileText(p_FileFullPath, getCharset());
                                    } else {
                                        retAts.writeRespCode("-1");
                                        retAts.writeRespInfo(p_sb.toString());
                                        retAts.writeEnd();
                                    }
                                } else {
                                    String curFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + curFileName;
                                    WriteBankLogLn("读取前置数据文件：" + curFilePath);
                                    curDataMFS = FileHelper.readFileText(curFilePath, getCharset());
                                    WriteBankLogStep3(curDataMFS);
                                }
                            } else {
                                throw new Exception("请配置银行前置机回单目录");
                            }
                        } else {
                            curDataMFS = curBkReader.getFirstText("/ap/body/serial_record");
                        }
                        if (curDataMFS != null) {
                            StringBuilder curSbLog = new StringBuilder();
                            ArrayList<String[]> curDataList = MFSHelper.getTextArray(curDataMFS, "|", curFieldNum, curRecordNum + 1, curSbLog);
                            if (curSbLog.length() == 0) {
                                //region **字段映射表
                                        /*[0]交易日期（C8）|  [1]交易时间交易日期（C6）|    [2]主机流水号（C20）|  [3]请求号（20）
                                        |[4]借贷标志(C1)|     [5]交易金额(N15,2)|         [6]余额(N15,2)|       [7]对方账号户名(C140)
                                        |[8]对方账号(C35)|    [9]对方账号户名(C140)|       [10]对方行号(C12)|    [11]摘要(C60)|
                                         */
                                //endregion
                                for (int i = 1; i < curDataList.size(); i++) {
                                    String[] curRowDataArr = curDataList.get(i);
                                    if (serialMap != null) {
                                        //将交易日期和主机流水号放入serialMap
                                        serialMap.put(String.valueOf(i), curRowDataArr[0].trim() + "-" + curRowDataArr[2].trim() + "-" + curRowDataArr[3].trim());
                                    }
                                    RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                    tmpRetDetail.actArea = actArea;
                                    tmpRetDetail.actNum = curRowDataArr[1].trim();
                                    tmpRetDetail.recAccNum = curRowDataArr[8].trim();
                                    tmpRetDetail.recAccName = curRowDataArr[7].trim();
                                    tmpRetDetail.recAccBank = StringHelper.convertToDBC(curRowDataArr[10]).trim();
                                    tmpRetDetail.tranDate = Format.strToDateFormat("yyyyMMdd", "yyyy-MM-dd", curRowDataArr[0].trim());
                                    tmpRetDetail.tranTime = Format.strToDateFormat("yyyyMMddHHmmss", "yyyy-MM-dd HH:mm:ss", curRowDataArr[0].trim() + curRowDataArr[1].trim());
                                    tmpRetDetail.valueDate = tmpRetDetail.tranDate;
                                    String cdFlagStr = curRowDataArr[4]; // D 1 表示借 C 2 表示贷
                                    String tranAmtStr = curRowDataArr[5];
                                    if ("C".equals(cdFlagStr)) { //贷
                                        tmpRetDetail.cdFlag = "2";
                                    } else if ("D".equals(cdFlagStr)) { //借
                                        tmpRetDetail.cdFlag = "1";
                                    } else {
                                        tmpRespCode = "-1";
                                        tmpRespInfo = "借贷标志( " + cdFlagStr + ")无法识别，请与银行核对";
                                        break;
                                    }
                                    //回单号格式 日期+核心流水+子顺序号
                                    tmpRetDetail.receiptNo = curRowDataArr[0].trim() + curRowDataArr[2].trim() + curRowDataArr[3].trim();
                                    tmpRetDetail.tranAmt = tranAmtStr;
                                    tmpRetDetail.accBal = curRowDataArr[6].trim();
                                    tmpRetDetail.postTimestamp = tmpRetDetail.tranTime;
                                    tmpRetDetail.billType = "";
                                    tmpRetDetail.billNum = "";
                                    String purpose = curRowDataArr[11].trim();
                                    if (purpose.contains("＋")) {
                                        tmpRetDetail.abstr = purpose.substring(purpose.lastIndexOf("＋") + 1, purpose.length());
                                        tmpRetDetail.usage = purpose.substring(0, purpose.lastIndexOf("＋"));
                                    } else {
                                        tmpRetDetail.abstr = "";
                                        tmpRetDetail.usage = curRowDataArr[11];
                                    }
                                    tmpRetDetail.payCode = tmpRetDetail.usage;
                                    tmpRetDetail.comment = tmpRetDetail.usage;
//                                    tmpRetDetail.askNumber = "";
//                                    tmpRetDetail.reqBatchNO = curRowDataArr[29];
//                                    tmpRetDetail.cur = this.convertCurToATS(curRowDataArr[2]);
//                                    tmpRetDetail.seqId = "";
//                                    tmpRetDetail.isCollection = "";
                                    tmpRetDetail.originator = "";
//                                    tmpRetDetail.busType = curRowDataArr[13];
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                tmpRespCode = "-1";
                                tmpRespInfo = curSbLog.toString();
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = "数据为空";
                        }
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = curRetInfo;
                }
            } else {
                tmpRespCode = "-1";
                tmpRespInfo = curSbMsg.toString();
            }
        } else {
            tmpRespCode = "-1";
            tmpRespInfo = retStrArr[1];
        }
        resultMap.put("tmpRespCode", tmpRespCode);
        resultMap.put("tmpRespInfo", tmpRespInfo);
        return resultMap;
    }

    protected String[] sendToBank(String p_reqStr) throws Exception {
        //一：参数、对象定义
        String[] retStrArr = new String[]{"", ""};
        String tmpCharset = getCharset();
        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverIP + ":" + bankFront.serverPort);
        TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.serverPort), this);

        //二：组织报头
        p_reqStr = "00" + p_reqStr;
        byte[] tmpBytesBody = p_reqStr.getBytes(tmpCharset);
        String tmpHead = String.format("%010d", tmpBytesBody.length);
        byte[] tmpBytesHead = tmpHead.getBytes(tmpCharset);

        //三：封装请求报文：【报头】、【报体】
        byte[] tmpBytesSend = new byte[tmpBytesHead.length + tmpBytesBody.length];
        System.arraycopy(tmpBytesHead, 0, tmpBytesSend, 0, tmpBytesHead.length);
        System.arraycopy(tmpBytesBody, 0, tmpBytesSend, tmpBytesHead.length, tmpBytesBody.length);

        //四：发送报文
        WriteBankLogStep2(tmpHead + p_reqStr);
        TcpReceiver tmpReceiver = tmpClient.sendMessage(tmpBytesSend);
        //五：解析报文
        if (StringHelper.isNullOrEmpty(tmpReceiver.connState)) {
            String tmpBkStr = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
            WriteBankLogStep3(tmpBkStr);
        }
        retStrArr[0] = tmpReceiver.connState;
        if (tmpReceiver.isCompleted) {
            retStrArr[1] = new String(tmpReceiver.recBytes, tmpReceiver.contentStartIndex, tmpReceiver.contentLength, tmpCharset);
        } else {
            retStrArr[1] = tmpReceiver.getConnMsg();
            WriteBankLogLn(retStrArr[1]);
        }

        return retStrArr;
    }

    protected void writeCommonHeader(XmlTextWriter xmlWriter, SRB01Header srb01Header, boolean fileFlag) {
        xmlWriter.writeStartDocument();
        xmlWriter.writeStartElement("ap");
        xmlWriter.writeStartElement("head");
        xmlWriter.writeElementString("tr_code", srb01Header.trCode);                                     //交易码
        xmlWriter.writeElementClosed("cms_corp_no");                                                     //银企客户号
        xmlWriter.writeElementClosed("user_no");                                                         //用户号
        xmlWriter.writeElementClosed("org_code");                                                        //机构号
        xmlWriter.writeElementClosed("serial_no");
        xmlWriter.writeElementString("req_no", srb01Header.reqSeqNo);
        if (srb01Header.reqDateTime == null) {
            srb01Header.reqDateTime = new Date();
        }
        xmlWriter.writeElementString("tr_acdt", Format.Date8Format.format(srb01Header.reqDateTime));  //交易日期
        xmlWriter.writeElementString("tr_time", Format.Time6Format.format(srb01Header.reqDateTime));  //交易时间
        xmlWriter.writeElementString("channel", "5");                                          //渠道标识
        xmlWriter.writeElementString("sign", "0");                                              //签名标识
        xmlWriter.writeElementString("file_flag", fileFlag ? "1" : "0");                                        //文件标识
        xmlWriter.writeElementClosed("reserved");                                                        //保留字段
        xmlWriter.writeEndElement();
    }

    protected String getCharset() {
        return getBankConfig().getCharset("GBK");
    }

    @Override
    public void getContentLength(TcpReceiver tcpReceiver) throws Exception {
        if (tcpReceiver.contentLength == -1) {
            if (tcpReceiver.readedLength >= 12) {
                String tmpHead = new String(tcpReceiver.recBytes, 0, 10, getCharset());
                tcpReceiver.contentLength = Integer.parseInt(tmpHead.trim()) - 2;
                tcpReceiver.contentStartIndex = 12;
            }
        }
    }
}
